﻿using Single.Core.Service;
using Single.Sugar.Db;
using Single.Sugar.Entity;
using SqlSugar;
using System.Linq.Expressions;

namespace Single.Sugar.Service
{
    public abstract class BaseService<T> : SugarService where T : BaseEntity, new()
    {
        // 数据操作对象
        protected DbRepository<T> rep;

        // 当前模型数据对象
        protected ISqlSugarClient dbRep => DbContext.DbScope.GetConnectionScopeWithAttr<T>();

        // 数据操作对象字典
        protected Dictionary<string, object> dicRep = new();

        protected DbRepository<T2> MoreRep<T2>() where T2 : BaseEntity, new()
        {
            return MoreRep<T2>(dbRep);
        }

        protected DbRepository<T2> MoreRep<T2>(ISqlSugarClient moreDb) where T2 : BaseEntity, new()
        {
            var key = $"{moreDb.ContextID}_{typeof(T2).FullName}";

            DbRepository<T2> rep;

            if (!dicRep.ContainsKey(key))
            {
                rep = new DbRepository<T2>(moreDb);
                dicRep.Add(key, rep);
            }
            else { rep = dicRep[key] as DbRepository<T2>; }

            return rep;
        }

        protected BaseService()
        {
            rep = new DbRepository<T>(dbRep);
        }

        public virtual T Get(long id)
        {
            return rep.GetById(id);
        }

        public virtual List<T> GetAll()
        {
            return rep.GetList();
        }

        public virtual List<T> GetPageList(int pageNum, int pageSize, out int total)
        {
            return rep.AsQueryable().ToPageList(pageNum, pageSize, out total);
        }

        public virtual ServiceResult InsertOrUpdate(T entity)
        {
            return UnknownResult(rep.InsertOrUpdate(entity), data: entity);
        }

        public virtual ServiceResult Insert(T entity)
        {
            return UnknownResult(rep.Insert(entity));
        }

        public virtual ServiceResult Insert(List<T> entities)
        {
            return UnknownResult(rep.InsertRange(entities));
        }

        public virtual ServiceResult Update(T entity)
        {
            return UnknownResult(rep.Update(entity));
        }

        public virtual ServiceResult Update(List<T> entities)
        {
            return UnknownResult(rep.UpdateRange(entities));
        }

        public virtual ServiceResult Delete(long id)
        {
            return UnknownResult(rep.DeleteById(id));
        }

        public virtual ServiceResult Delete(long[] ids)
        {
            return UnknownResult(rep.Delete(m => ids.Contains(m.Id)));
        }

        public virtual ServiceResult Delete(T entity)
        {
            return UnknownResult(rep.Delete(entity));
        }

        public virtual ServiceResult Delete(List<T> entities)
        {
            return UnknownResult(rep.Delete(entities));
        }
    }
}